#include <blackbox/blackbox.h>
#include <blackbox/boxes/bperiodic.h>
#include <blackbox/cscheduler.h>
#include <blackbox/proxies.h>
#include <blackbox/connect.h>

#include <buola/media/codec/bffmpegdecoder.h>
#include <blackbox/boxes/io/bfilesrc.h>
#include <blackbox/boxes/io/bfilesink.h>
#include <buola/media/audio/bpulsesink.h>
#include <buola/media/codec/bmp3decoder.h>
#include <blackbox/boxes/bdiskimagewriter.h>
#include <blackbox/boxes/bimagedisplay.h>
#include <buola/app/ccmdline.h>

using namespace buola;
using namespace buola::blackbox;

class CTestFfmpegMachine
{
public:
    CTestFfmpegMachine(const io::CURI &pURI)
        :   mFileSrc(pURI)
    {
        msg_info() << "creating machine!!!\n";
        mFileSrc.ChangeState(BBox::STATE_ACTIVE);
        bb_connect(mFileSrc.oData,mDecoder.iData);
        mDecoder.ChangeState(BBox::STATE_ACTIVE);
        bb_connect(*mDecoder.oAudio[0],mPulseSink.iWave);
        bb_connect(*mDecoder.oVideo[0],mDisplay.iImage);
        bb_connect(*mDecoder.kVideo[0],mDisplay.kIn);

        thread(std::bind(&CTestFfmpegMachine::LoopThread,this)).detach();
    }

    void LoopThread()
    {
        while(true)
        {
            mDecoder.Loop();
        }
    }

private:
    BFileSrc mFileSrc;
    media::BFfmpegDecoder mDecoder;
    media::BPulseSink mPulseSink;
    BImageDisplay mDisplay;
};

int main(int pNArgs,char **pArgs)
{
    buola_init(pNArgs,pArgs);

    try
    {
        io::CURI lURI=io::get_home()/"test"/"test.wmv";
        if(cmd_line().ArgCount())
            lURI=io::file(cmd_line().Arg(0));
        CTestFfmpegMachine lMachine(lURI);
        buola_main_loop();
    }
    catch(std::exception &pE)
    {
        msg_error() << "caught exception " << pE.what() << "\n";
    }

    return buola_finish();
}
